package com.mcp.weather.util;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.function.Function;

/**
 * JSON-RPC 协议处理器
 */
public class JsonRpcHandler {
    private static final Logger logger = LoggerFactory.getLogger(JsonRpcHandler.class);
    private static final ObjectMapper objectMapper = new ObjectMapper()
            .setSerializationInclusion(JsonInclude.Include.NON_NULL);

    /**
     * 处理 JSON-RPC 请求
     */
    public static String handleRequest(String requestJson, Function<String, JsonNode> methodHandler) {
        try {
            JsonNode request = objectMapper.readTree(requestJson);
            
            // 验证 JSON-RPC 版本
            if (!request.has("jsonrpc") || !"2.0".equals(request.get("jsonrpc").asText())) {
                // 版本无效时不返回响应（因为可能是通知）
                return null;
            }

            String method = request.has("method") ? request.get("method").asText() : null;
            JsonNode params = request.has("params") ? request.get("params") : null;
            JsonNode id = request.has("id") ? request.get("id") : null;
            
            // 判断是否为通知（没有 id 字段）
            boolean isNotification = (id == null || id.isNull());

            if (method == null) {
                // 如果请求无效，只有在有 id 时才返回错误响应
                return isNotification ? null : createErrorResponse(id, -32600, "Invalid Request", null);
            }

            // 调用方法处理器
            JsonNode result = methodHandler.apply(method);
            if (result == null) {
                // 方法不存在：如果是通知，不返回响应；如果是请求，返回错误
                return isNotification ? null : createErrorResponse(id, -32601, "Method not found", null);
            }

            // 如果是通知，不返回响应
            if (isNotification) {
                return null;
            }

            // 构建成功响应（只有请求才需要响应）
            ObjectNode response = objectMapper.createObjectNode();
            response.put("jsonrpc", "2.0");
            response.set("id", id);
            response.set("result", result);

            return objectMapper.writeValueAsString(response);

        } catch (Exception e) {
            logger.error("处理 JSON-RPC 请求失败", e);
            try {
                JsonNode request = objectMapper.readTree(requestJson);
                JsonNode id = request.has("id") ? request.get("id") : null;
                // 解析错误：如果是通知，不返回响应；如果是请求，返回错误
                boolean isNotification = (id == null || id.isNull());
                return isNotification ? null : createErrorResponse(id, -32700, "Parse error", null);
            } catch (Exception ex) {
                // 无法解析请求，不返回响应
                return null;
            }
        }
    }

    /**
     * 创建错误响应
     * 注意：此方法只用于请求（有 id），不用于通知（无 id）
     */
    private static String createErrorResponse(JsonNode id, int code, String message, Object data) {
        try {
            ObjectNode response = objectMapper.createObjectNode();
            response.put("jsonrpc", "2.0");
            // 错误响应必须有 id（因为只用于请求）
            response.set("id", id);

            ObjectNode error = objectMapper.createObjectNode();
            error.put("code", code);
            error.put("message", message);
            if (data != null) {
                error.set("data", objectMapper.valueToTree(data));
            }
            response.set("error", error);

            return objectMapper.writeValueAsString(response);
        } catch (Exception e) {
            logger.error("创建错误响应失败", e);
            return "{\"jsonrpc\":\"2.0\",\"id\":null,\"error\":{\"code\":-32603,\"message\":\"Internal error\"}}";
        }
    }

    /**
     * 获取 ObjectMapper 实例
     */
    public static ObjectMapper getObjectMapper() {
        return objectMapper;
    }
}

